package services.common;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import models.common.bean.CommercialPaperBean;
import models.common.bean.CommercialTicket;
import models.common.bean.receivable.PaperInfoToLoadBid;
import models.common.entity.t_commercial_paper_info;
import models.common.entity.t_commercial_paper_info.TicketStatus;
import models.common.entity.t_company_info;
import models.common.entity.t_creditor_right_debt;
import models.common.entity.t_deal_user;
import models.common.entity.t_deal_user.OperationType;
import models.common.entity.t_digital_commercial_paper;
import models.common.entity.t_digital_commercial_paper.DigitalStatus;
import models.common.entity.t_template_notice;
import models.common.entity.t_user;
import models.common.entity.t_user_credit;
import models.common.entity.t_user_credit.AuditResult;
import models.common.entity.t_user_credit_detail;
import models.common.entity.t_user_fund;

import org.apache.commons.lang.StringUtils;

import play.db.jpa.JPAPlugin;
import services.base.BaseService;

import common.constants.SettingKey;
import common.enums.NoticeScene;
import common.enums.ServiceType;
import common.enums.Type;
import common.utils.DateUtil;
import common.utils.Factory;
import common.utils.FeeCalculateUtil;
import common.utils.ImgUtil;
import common.utils.LoggerUtil;
import common.utils.OrderNoUtil;
import common.utils.PageBean;
import common.utils.ResultInfo;
import common.utils.StrUtil;
import common.utils.number.Arith;
import common.utils.zjtx.SMSUtil;

import controllers.common.FrontBaseController;
import daos.common.CommerciaPaperiInfoDao;

/**
 * 商票信息表service
 * 
 * @author xiaojun
 * @version 2017-4-14 下午4:24:31
 */
public class CommerciaPaperiInfoService extends
		BaseService<t_commercial_paper_info> {

	private CommerciaPaperiInfoDao commerciaPaperiInfoDao;
	protected static CibBankService cibBankService = Factory
			.getService(CibBankService.class);

	protected CommerciaPaperiInfoService() {
		commerciaPaperiInfoDao = Factory.getDao(CommerciaPaperiInfoDao.class);
		super.basedao = commerciaPaperiInfoDao;
	}

	/** 注入系统设置service */
	protected static SettingService settingService = Factory
			.getService(SettingService.class);

	protected static CreditorRightDebtService creditorRightDebtService = Factory
			.getService(CreditorRightDebtService.class);

	protected static NoticeService noticeService = Factory
			.getService(NoticeService.class);

	protected static SendCodeRecordsService sendCodeRecordsService = Factory
			.getService(SendCodeRecordsService.class);

	protected static FlowSwitchService flowSwitchService = Factory
			.getService(FlowSwitchService.class);

	protected static DigitalCommercialPaperService digitalCommercialPaperService = Factory
			.getService(DigitalCommercialPaperService.class);

	protected static EndorseService endorseService = Factory
			.getService(EndorseService.class);

	protected static UserCreditDetailService userCreditDetailService = Factory
			.getService(UserCreditDetailService.class);

	protected static UserCreditService userCreditService = Factory
			.getService(UserCreditService.class);

	protected static UserFundService userFundService = Factory
			.getService(UserFundService.class);

	protected static DealUserService dealUserService = Factory
			.getService(DealUserService.class);
	
	protected static UserService userService = Factory
			.getService(UserService.class);
	

	/**
	 * 前台-交易管理-质押管理
	 * 
	 * @param showType
	 * @param currPage
	 * @param pageSize
	 * @param exports
	 * @param orderType
	 * @param orderValue
	 * @param creditorName
	 * @param numNo
	 * @param debtPersonName
	 * @return
	 * @author xiaojun
	 * @createDate 2017年4月15日
	 */
	public PageBean<t_commercial_paper_info> pageOfPledgeTicket(int showType,
			int currPage, int pageSize, int exports, long user_id,
			String checkin_time, String to_checkin_time, int type,
			int is_digital) {
		return commerciaPaperiInfoDao.pageOfPledgeTicket(showType, currPage,
				pageSize, exports, user_id, checkin_time, to_checkin_time,
				type, is_digital);

	}

	/**
	 * 新增商票数据校验
	 * 
	 * @param paper_pic_on
	 *            正面图片
	 * @param paper_pic_under
	 *            反面图片
	 * @param paper_money
	 *            票面金额
	 * @param bill_code
	 *            票号
	 * @param account_num
	 *            开户账号
	 * @param account_bank
	 *            开户银行
	 * @param drawee
	 *            承兑人
	 * @param paper_expire_time
	 *            商票到期时间
	 * @param paper_create_time
	 *            商票起始时间
	 * @param lender_id
	 *            放款人id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-17
	 */
	public ResultInfo addTicketVlidate(String paper_pic_on,
			String paper_pic_under, double paper_money, String bill_code,
			String account_num, String account_bank, String drawee,
			String paper_expire_time, String paper_create_time, long lender_id) {
		ResultInfo result = new ResultInfo();
		if (lender_id <= 0) {
			result.code = -1;
			result.msg = "请选择付款人";
			return result;
		}
		if (StringUtils.isBlank(bill_code)) {
			result.code = -1;
			result.msg = "请填写凭证号码";
			return result;
		}
		if (paper_money <= 0) {
			result.code = -1;
			result.msg = "请填写正确的金额";
			return result;
		}
		if (StringUtils.isBlank(paper_create_time)) {
			result.code = -1;
			result.msg = "请填写商票开票日期";
			return result;
		}
		if (!StrUtil.is_date(paper_create_time)) {
			result.code = -1;
			result.msg = "商票开票日期格式不正确";
			return result;
		}
		if (StringUtils.isBlank(paper_expire_time)) {
			result.code = -1;
			result.msg = "请填写商票到期日期";
			return result;
		}
		if (!StrUtil.is_date(paper_expire_time)) {
			result.code = -1;
			result.msg = "商票到期日期格式不正确";
			return result;
		}
		Date create_time = DateUtil.strToDate(paper_create_time, "yy/MM/dd");
		
		Date expire_time = DateUtil.strToDate(paper_expire_time, "yy/MM/dd");
		
		if(DateUtil.isDateAfter(create_time, expire_time)){
			result.code = -1;
			result.msg = "质押商票的起始时间不能在到期日期之后！";
			return result;
		}
		
		Map<String, Integer> monthsAndDays = FeeCalculateUtil.getMonthsAndDays(create_time, expire_time);
		
		//获取当前的时间到商票结束时间的间隔（规则间隔）
		int days = monthsAndDays.get("monCount")*30 + monthsAndDays.get("counrt");
		if(days <= 13){
			result.code = -1;
			result.msg = "质押商票的天数要大于十三天！";
			return result;
		}
		
		if (DateUtil.isDateBefore(DateUtil.strToDate(paper_expire_time, "yyyy/MM/dd"),new Date())) {
			result.code = -1;
			result.msg = "商票到期时间不能在当前日期之前";
			return result;
		}
		if (StringUtils.isBlank(drawee)) {
			result.code = -1;
			result.msg = "请填写承兑人";
			return result;
		}
		if (StringUtils.isBlank(account_num)) {
			result.code = -1;
			result.msg = "请填写开户账号";
			return result;
		}
		if (account_num.length() > 24 || account_num.length() < 9) {
			result.code = -1;
			result.msg = "请正确填写开户账号";
			return result;
		}
		if (StringUtils.isBlank(account_bank)) {
			result.code = -1;
			result.msg = "请填写开户银行";
			return result;
		}

		if (StringUtils.isBlank(paper_pic_on)) {
			result.code = -1;
			result.msg = "请上传商票图片（正面）";
			return result;
		}
		if (StringUtils.isBlank(paper_pic_under)) {
			result.code = -1;
			result.msg = "请上传商票图片（反面）";
			return result;
		}
		return result;

	}

	/**
	 * 新增商票
	 * 
	 * @param paper_pic_on
	 *            正面图片
	 * @param paper_pic_under
	 *            反面图片
	 * @param paper_money
	 *            票面金额
	 * @param bill_code
	 *            票号
	 * @param account_num
	 *            开户账号
	 * @param account_bank
	 *            开户银行
	 * @param drawee
	 *            承兑人
	 * @param paper_expire_time
	 *            商票到期时间
	 * @param paper_create_time
	 *            商票起始时间
	 * @param lender_id
	 *            放款人id
	 * @param user_id
	 *            当前用户id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-17
	 */
	public ResultInfo addTicket(String paper_pic_on, String paper_pic_under,
			double paper_money, String bill_code, String account_num,
			String account_bank, String drawee, String paper_expire_time,
			String paper_create_time, long userCreditId, long user_id,
			t_user_credit user_credit) { // 新增商票信息
		ResultInfo result = new ResultInfo();

		if (DateUtil.isDateBefore(user_credit.end_time,
				DateUtil.strToDate(paper_expire_time, "yyyy/MM/dd"))) {
			result.code = -1;
			result.msg = "商票到期时间不能大于授信额度到期时间";
			return result;
		}
		t_commercial_paper_info cpi = new t_commercial_paper_info();

		cpi.bill_code = bill_code;
		cpi.paper_create_time = DateUtil.strToDate(paper_create_time,
				"yyyy/MM/dd");
		cpi.paper_expire_time = DateUtil.strToDate(paper_expire_time,
				"yyyy/MM/dd");

		cpi.paper_money = paper_money;
		cpi.drawee = drawee;
		cpi.account_num = account_num;
		cpi.account_bank = account_bank;
		cpi.paper_pic_on = paper_pic_on;
		cpi.paper_pic_under = paper_pic_under;
		t_company_info company_info = companyInfoService
				.findCompanyInfoByUserId(user_id);
		cpi.receive_id = user_id;
		cpi.receive_name = company_info.full_name;
		cpi.receive_bank = company_info.open_bank;
		cpi.receive_num = company_info.open_account;

		cpi.lender_id = user_credit.lender_id;
		cpi.lender_name = user_credit.lender_name;
		cpi.credit_limit_id = user_credit.id;
		cpi.finacing_residue_limit = cpi.paper_money;
		cpi.time = new Date();
		//TODO
		if(user_credit.parent_id == 0){
			cpi.receive_credit_id = user_credit.id;
		}else{
			cpi.receive_credit_id = user_credit.parent_id;
		}
		/*if(user_credit.getStatus().code == AuditResult.TRANSFER.code ){
			 // 获取系统默认融通比例
			cpi.finacing_ratio = Double.valueOf(settingService.findSettingValueByKey(SettingKey.FINACING_RATIO));;
		}else{
			
			cpi.finacing_ratio = user_credit.financing_confine_limit;
		}*/
		cpi.finacing_ratio = user_credit.financing_confine_limit;
		// cpi.paper_status = TicketStatus.NOT_SIGN.code;
		cpi = addTicket(cpi);
		if (cpi == null) {
			LoggerUtil.info(true, "登记商票失败");
			result.msg = "登记商票失败";
			result.code = -1;
			return result;
		}

		//减少融通申请质押商票的授信可质押额度
		
		t_user_credit userCredit = userCreditService.findByID(cpi.credit_limit_id);
		if(userCredit == null ){
			LoggerUtil.error(true,  "获取不到商票对应的授信信息！");
			result.code = -1;
			result.msg = "获取不到商票对应的授信信息！";
			return result;
		}
		if(userCredit.pledged_limit < 0 || userCredit.pledged_limit < cpi.paper_money){
			LoggerUtil.error(true,  "商票对应的授信可质押额度不足！");
			result.code = -1;
			result.msg = "商票对应的授信可质押额度不足！";
			return result;
		}
		userCredit.pledged_limit = userCredit.pledged_limit - cpi.paper_money;
		
		boolean flag = userCreditService.save(userCredit);
		if(!flag){
			LoggerUtil.error(true,  "更新商票对应的授信可质押额度异常！");
			result.code = -1;
			result.msg = "更新商票对应的授信可质押额度异常！";
			return result;
		}
		
		// 发送通知
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", cpi.lender_name);
		param.put("bill_code", cpi.bill_code);
		param.put("amount", cpi.paper_money);
		param.put("full_name", user_credit.user_name);
		noticeService
				.sendSysNotice(cpi.lender_id, NoticeScene.PLEDGE_OK, param);

		result.msg = "新增商票成功！";
		result.code = 2;
		result.obj = cpi.id;
		return result;
	}

	/**
	 * 确认接收质押
	 * 
	 * @param cpiId
	 * @param user_id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-17
	 */
	public ResultInfo confirmPledge(long cpiId, long user_id) {
		ResultInfo result = new ResultInfo();
		t_commercial_paper_info cpi = findByID(cpiId);
		if (null == cpi || cpi.paper_status != TicketStatus.REGISTER.code) {
			result.code = -1;
			result.msg = "商票状态异常！";
			return result;
		}
		if(!DateUtil.isDatetimeAfter(cpi.paper_expire_time,new Date())){
			result.code = -1;
			result.msg = "接收质押商票的时间不能在商票到期日期之后！！";
			return result;
		}
		if (user_id != cpi.lender_id) {
			result.code = -1;
			result.msg = "警告！禁止操作";
			return result;
		}
		int i = upPaperStatus(TicketStatus.PLEDGE.code,
				TicketStatus.REGISTER.code, cpiId);
		if (i != 1) {
			result.code = -1;
			result.msg = "商票状态更新异常！";
			return result;
		}
		
		// 发送通知
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", cpi.receive_name);
		param.put("bill_code", cpi.bill_code);
		noticeService.sendSysNotice(cpi.receive_id, NoticeScene.PLEDGE_YES,
				param);

		result.code = 1;
		result.msg = "操作成功";
		return result;
	}

	/**
	 * 通知挂牌
	 * 
	 * @param cpiId
	 * @param user_id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-17
	 */
	public ResultInfo notificationListing(long cpiId, long user_id) {
		ResultInfo result = new ResultInfo();
		t_commercial_paper_info cpi = findByID(cpiId);
		if (null == cpi || cpi.paper_status != TicketStatus.PLEDGE.code) {
			result.code = -1;
			result.msg = "商票状态异常！";
			return result;
		}
		if (user_id != cpi.lender_id) {
			result.code = -1;
			result.msg = "警告！禁止操作";
			return result;
		}
		/*if (notificationType == 2) {
			// 发送通知
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("user_name", cpi.receive_name);
			param.put("bill_code", cpi.bill_code);
			noticeService.sendSysNotice(cpi.receive_id,
					NoticeScene.NOTIFICATION_SUMIT_DEPOSIT, param);
			result.code = 1;
			result.msg = "通知成功";
			return result;
		}*/

		cpi.is_listing = 1;
		cpi = addTicket(cpi);
		if (cpi == null) {
			result.code = -1;
			result.msg = "商票挂牌状态更新异常！";
			return result;
		}
		// 发送通知
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", cpi.receive_name);
		param.put("bill_code", cpi.bill_code);
		noticeService.sendSysNotice(cpi.receive_id,
				NoticeScene.NOTIFICATION_LISTING, param);
		result.code = 1;
		result.msg = "通知成功";
		return result;
	}

	/**
	 * 告知解除质押
	 * 
	 * @param cpiId
	 * @param user_id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-17
	 */
	public ResultInfo removePledge(long cpiId, long user_id) {
		ResultInfo result = new ResultInfo();
		t_commercial_paper_info cpi = findByID(cpiId);
		if (null == cpi || cpi.paper_status != TicketStatus.PLEDGE.code) {
			result.code = -1;
			result.msg = "商票状态异常！";
			return result;
		}
		if (user_id != cpi.lender_id) {
			result.code = -1;
			result.msg = "警告！禁止操作";
			return result;
		}
		if (cpi.paper_money != cpi.finacing_residue_limit) {
			result.code = -1;
			result.msg = "当前商票不可以解除质押！";
			return result;
		}
		int i = upPaperStatus(TicketStatus.INVALID.code,
				TicketStatus.PLEDGE.code, cpiId);
		if (i != 1) {
			result.code = -1;
			result.msg = "解除质押失败！状态异常";
			return result;
		}
		
		t_user_credit user_credit = userCreditService.findByID(cpi.credit_limit_id);
		
		if(user_credit == null){
			LoggerUtil.error(true, "获取不到商票对应的授信额度信息");
			result.code = -1;
			result.msg = "获取不到商票对应的授信额度信息";
			return result;
		}
		
		if(cpi.finacing_residue_limit > 0){
			user_credit.pledged_limit += cpi.finacing_residue_limit;
			boolean flag = userCreditService.save(user_credit);
			if(!flag){
				LoggerUtil.error(true, "更新商票对应授信额度的可质押额度时异常");
				result.code = -1;
				result.msg = "更新商票对应授信额度的可质押额度时异常";
				return result;
			}
		}
		
		// 发送通知
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", cpi.receive_name);
		param.put("bill_code", cpi.bill_code);
		noticeService.sendSysNotice(cpi.receive_id, NoticeScene.REMOVE_PLEDGE,
				param);
		result.code = 1;
		result.msg = "通知成功";
		return result;
	}

	/**
	 * 通知划款
	 * 
	 * @param cpiId
	 * @param user_id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-17
	 */
	public ResultInfo cashPledge(long cpiId, long user_id) {
		ResultInfo result = new ResultInfo();
		t_commercial_paper_info cpi = findByID(cpiId);
		if (null == cpi || cpi.paper_status != TicketStatus.EXPIRE.code
				|| cpi.is_digital != 1) {
			result.code = -1;
			result.msg = "商票状态异常！";
			return result;
		}

		if (user_id != cpi.lender_id) {
			result.code = -1;
			result.msg = "警告！禁止操作";
			return result;
		}

		int i = upPaperStatus(TicketStatus.REPAYMENT.code,
				TicketStatus.EXPIRE.code, cpiId);
		if (i != 1) {
			result.code = -1;
			result.msg = "通知划款失败！状态异常";
			return result;
		}
		boolean updateStatus = false;
		if (cpi.is_endorse == 1) { // 1 已背书
			updateStatus = endorseService.updateStatus(
					DigitalStatus.REPAYMENT.code, 0, cpi.circulation_id);
		} else {
			updateStatus = digitalCommercialPaperService.updateStatus(
					DigitalStatus.REPAYMENT.code, 0, cpi.circulation_id);
		}
		if (!updateStatus) {
			result.code = -1;
			result.msg = "通知划款失败！修改状态异常";
			return result;
		}
		
		t_user_credit user_credit = userCreditService.findByID(cpi.receive_credit_id);
		
		if(user_credit == null){
			result.code = -1;
			result.msg = "获取当前商票授信信息失败";
			return result;
		}
		
		//如果商票到期时间在授信截止时间之前，需要返还授信额度给质押商票的企业
		if(!DateUtil.isDateAfter(cpi.paper_expire_time, user_credit.end_time) && cpi.orginal_paper_id > 0){
			t_commercial_paper_info paperInfo = commerciaPaperiInfoDao.findByID(cpi.orginal_paper_id);
			
			Type type = Type.getEnum(1);
			double paperAmount = Arith.add(cpi.finacing_residue_limit,cpi.finacing_used_limit);
			//还额度
			result = doStillQuota(type, paperAmount ,paperInfo.receive_id,paperInfo.credit_limit_id);
			if (result.code < 1) {
				result.code = -1;
				result.msg = result.msg;
				return result;
			}
			
		}
		
		
		// 发送通知
		t_company_info company_info = companyInfoService
				.findByUserId(cpi.receive_id);
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", company_info.full_name);
		param.put("bill_code", cpi.certificate_code);
		param.put("paper_money", cpi.finacing_residue_limit);
		noticeService.sendSysNotice(cpi.receive_id,
				NoticeScene.EXPIRE_REIMBURSEMENT, param);
		
		t_user_fund userFund = userFundService.findByColumn(" user_id = ?", cpi.receive_id);
		
		String serviceOrderNo = OrderNoUtil.getNormalOrderNo(
				ServiceType.OFFLINE_RECEIVE, "");
		Map<String, String> summaryParam = new HashMap<String, String>();
		summaryParam.put("code", cpi.certificate_code);
		summaryParam.put("amount", Double.toString(Arith.add(cpi.finacing_residue_limit,cpi.finacing_used_limit)));
		/*boolean flag = dealUserService.addDealUserInfo(serviceOrderNo, cpi.receive_id,Arith.add(cpi.finacing_residue_limit,cpi.finacing_used_limit),
				userFund.balance, userFund.freeze, OperationType.COLLECTION_PAY_VOUCHER, summaryParam);
		if(!flag){
			result.code = -1;
			result.msg = "凭证收票人托收流水记录添加失败";
			return result;
		}*/
		t_user_fund user_fund = userFundService.findByColumn("user_id = ? ", user_id);
		
		serviceOrderNo = OrderNoUtil.getNormalOrderNo(
				ServiceType.OFFLINE_RECEIVE, "");
		Map<String, String> sumParam = new HashMap<String, String>();
		sumParam.put("code", cpi.bill_code);
		sumParam.put("amount", Double.toString(Arith.add(cpi.finacing_residue_limit,cpi.finacing_used_limit)));
		/*flag = dealUserService.addDealUserInfo(serviceOrderNo, user_id,Arith.add(cpi.finacing_residue_limit,cpi.finacing_used_limit),
				user_fund.balance, user_fund.freeze, OperationType.COLLECTION_PAY_PLAT_VOUCHER, sumParam);
		if(!flag){
			result.code = -1;
			result.msg = "放款人确认划款流水记录添加失败";
			return result;
		}*/
		result.code = 1;
		result.msg = "通知成功";
		return result;
	}

	/**
	 * 创建保证金
	 * 
	 * @param cpiId
	 * @param user_id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-17
	 */
	public ResultInfo creationBond(t_commercial_paper_info cpi, long user_id) {
		ResultInfo result = new ResultInfo();
		if (null == cpi || cpi.paper_status != TicketStatus.NOT_SIGN.code) {
			result.code = -1;
			result.msg = "商票状态异常！";
			return result;
		}

		if (user_id != cpi.receive_id) {
			result.code = -1;
			result.msg = "警告！禁止操作";
			return result;
		}

		int i = upPaperStatus(TicketStatus.REGISTER.code,
				TicketStatus.NOT_SIGN.code, cpi.id);
		if (i != 1) {
			result.code = -1;
			result.msg = "合同签署失败！状态异常";
			return result;
		}
		t_user_credit user_credit = userCreditService
				.findByID(cpi.credit_limit_id);
		if (user_credit == null) {
			result.code = -1;
			result.msg = "查询商票对应授信信息异常";
			return result;
		}
		// 发送通知
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", cpi.lender_name);
		param.put("bill_code", cpi.bill_code);
		param.put("amount", cpi.paper_money);
		param.put("full_name", user_credit.user_name);
		noticeService
				.sendSysNotice(cpi.lender_id, NoticeScene.PLEDGE_OK, param);

		result.code = 1;
		result.msg = "通知成功";
		result.obj = user_credit;
		return result;
	}

	/**
	 * 后台 -风控 -质押商票审核-管理员修改商票正反面
	 * 
	 * @param type
	 *            1为paper_pic_under 2为paper_pic_on
	 * @param url
	 *            图片地址
	 * @param id
	 *            商票id
	 * @return
	 * @author xiaojun
	 * @createDate 2017年4月26日
	 */
	public boolean upPaperPic(int type, String url, long id) {

		return commerciaPaperiInfoDao.upPaperPic(type, url, id);

	}

	/**
	 * 后台 -风控-商票管理列表
	 * 
	 * @param showType
	 * @param currPage
	 * @param pageSize
	 * @param exports
	 * @param orderType
	 * @param orderValue
	 * @param creditorName
	 * @param numNo
	 * @param debtPersonName
	 * @return
	 * @author xiaojun
	 * @createDate 2017年4月15日
	 */
	public PageBean<CommercialTicket> pageOfCommercialTicket(int orderValue,int showType,
			int currPage, int pageSize, int exports, int orderType,
			String drawee, String receive_name,
			String lender_name, int is_digital) {
		return commerciaPaperiInfoDao.pageOfCommercialTicket(showType,
				currPage, pageSize, exports, orderType, orderValue, drawee,
				receive_name, lender_name, is_digital);

	}
	/**
	 * 后台 -风控-商票管理列表
	 * 
	 * @param showType
	 * @param currPage
	 * @param pageSize
	 * @param exports
	 * @param orderType
	 * @param orderValue
	 * @param creditorName
	 * @param numNo
	 * @param debtPersonName
	 * @return
	 * @author xiaojun
	 * @createDate 2017年4月15日
	 */
	public PageBean<CommercialTicket> pageOfCommercialOfTicket(int orderValue,int showType,
			int currPage, int pageSize, int exports, int orderType,
			 String drawee, String receive_name,
			String lender_name, int is_digital) {
		return commerciaPaperiInfoDao.pageOfCommercialOfTicket(orderValue,showType,
				currPage, pageSize, exports, orderType, drawee,
				receive_name, lender_name, is_digital);
		
	}

	/**
	 * 后台-风控页面-质押管理的列表计算商票金额
	 * 
	 * @param showType
	 *            筛选类型 0全部 1审核中 2 已质押3 已完成 4 未通过 5 已失效 6 已到期 7 已逾期 8 待签字 9已签字
	 * @param creditorName
	 *            债权人全称
	 * @param numNo
	 * @param debtPersonName
	 *            债务人全称
	 * @return
	 * @author xiaojun
	 * @createDate 2017年4月15日
	 */
	public double findTotalTicketAmount(int orderValue,int showType, String drawee,
			String receive_name, String lender_name, int is_digital) {
		return commerciaPaperiInfoDao.findTotalTicketAmount(orderValue,showType, drawee,
				receive_name, lender_name, is_digital);
	}
	/**
	 * 后台-风控页面-商票管理的列表计算商票金额
	 * 
	 * @param showType
	 *            筛选类型 0全部 1审核中 2 已质押3 已完成 4 未通过 5 已失效 6 已到期 7 已逾期 8 待签字 9已签字
	 * @param creditorName
	 *            债权人全称
	 * @param numNo
	 * @param debtPersonName
	 *            债务人全称
	 * @return
	 * @author xiaojun
	 * @createDate 2017年4月15日
	 */
	public double findTotalPaperAmount(int orderValue,int showType, String drawee,
			String receive_name, String lender_name, int is_digital) {
		return commerciaPaperiInfoDao.findTotalPaperAmount(orderValue,showType, drawee,
				receive_name, lender_name, is_digital);
	}

	/**
	 * 前台-账户中心-交易管理-商票登记
	 * 
	 * @param t
	 *            商票实体
	 * @return
	 * @author xiaojun
	 * @version 2017-5-3 下午7:20:42
	 */
	public t_commercial_paper_info addTicket(t_commercial_paper_info t) {

		boolean save = commerciaPaperiInfoDao.save(t);
		if (save) {
			return t;
		}
		return null;

	}

	/**
	 * 审核
	 * 
	 * @param t
	 * @return
	 * @author xiaojun
	 * @version 2017-9-4
	 */
	public boolean updateTicket(t_commercial_paper_info t) {
		return commerciaPaperiInfoDao.updatePaper(t.paper_pic_under,
				t.paper_pic_on, t.receive_id, t.id, t.finacing_residue_limit);
	}

	/**
	 * 前台-账户中心-交易管理-商票登记
	 * 
	 * @param t
	 *            商票实体
	 * @return
	 * @author xiaojun
	 * @version 2017-5-3 下午7:20:42
	 */

	protected static CompanyInfoService companyInfoService = Factory
			.getService(CompanyInfoService.class);

	/**
	 * 定时任务 标记商票到期
	 * 
	 * @return
	 * @author xiaojun
	 * @version 2017-5-3
	 * @param bondService 
	 */
	public ResultInfo systemTicketMarkExpire() {

		return commerciaPaperiInfoDao.autoTicketMarkExpire();

	}

	/**
	 * 定时任务 商票到期前3天 和当天 提醒用户
	 * 
	 * @return
	 * @author xiaojun
	 * @version 2017-5-3
	 */
	public ResultInfo ticketExpireRemind() {
		ResultInfo result = new ResultInfo();

		// 查询今天或者一个星期后到期的“正常待还”和“本息垫付待还”账单
		List<Map<String, Object>> listOfWillExpireTicket = commerciaPaperiInfoDao
				.querylistOfWillExpireTicket();

		if (listOfWillExpireTicket == null
				|| listOfWillExpireTicket.size() == 0) {
			result.code = 1;
			result.msg = "当前没有需要提醒的到期商票!";

			return result;
		}

		int success = 0;
		/* 关闭自动事务 */
		JPAPlugin.closeTx(false);
		for (Map<String, Object> mapBill : listOfWillExpireTicket) {
			/* 开启自动事务 */
			JPAPlugin.startTx(false);
			Map<String, Object> sceneParame = new HashMap<String, Object>();
			sceneParame.put("user_name", mapBill.get("drawee"));
			sceneParame.put("bill_code", mapBill.get("bill_code"));
			sceneParame.put("contract_name_code","无");
			sceneParame.put("paper_expire_time", DateUtil.dateToString(
					(Date) mapBill.get("paper_expire_time"), "yyyy-MM-dd"));
			sceneParame.put("paper_money", mapBill.get("paper_money"));
			if (mapBill.get("userId") != null) {

				boolean send = noticeService.sendSysNotice(
						Long.parseLong(mapBill.get("userId").toString()),
						NoticeScene.TICKETEXPIREREMIND, sceneParame);
				if (send) {
					success++;
				}
			} 
			/* 关闭自动事务 */
			JPAPlugin.closeTx(false);
		}
		/* 开启自动事务 */
		JPAPlugin.startTx(false);

		result.code = 1;
		result.msg = "本次商票到期提醒总共通知" + listOfWillExpireTicket.size() + "人次，成功通知"
				+ success + "人次!";

		return result;

	}

	/**
	 * 定时任务 商票逾期前3天 和当天 提醒用户
	 * 
	 * @return
	 * @author xiaojun
	 * @version 2017-5-3
	 */
	public ResultInfo ticketOverdueRemind() {
		ResultInfo result = new ResultInfo();

		// 查询今天或者一个星期后到期的“正常待还”和“本息垫付待还”账单
		List<Map<String, Object>> listOfWillExpireTicket = commerciaPaperiInfoDao
				.querylistOfWillOverdueTicket();

		if (listOfWillExpireTicket == null
				|| listOfWillExpireTicket.size() == 0) {
			result.code = 1;
			result.msg = "当前没有需要提醒的逾期商票!";

			return result;
		}

		int success = 0;
		/* 关闭自动事务 */
		JPAPlugin.closeTx(false);
		for (Map<String, Object> mapBill : listOfWillExpireTicket) {
			/* 开启自动投标事务 */
			JPAPlugin.startTx(false);
			Map<String, Object> sceneParame = new HashMap<String, Object>();
			sceneParame.put("user_name", mapBill.get("drawee"));
			sceneParame.put("bill_code", mapBill.get("bill_code"));
			sceneParame.put("contract_name_code",
					mapBill.get("contract_name_code"));
			Date paper_expire_time = (Date) mapBill.get("paper_expire_time");
			sceneParame.put("paper_expire_time", DateUtil.dateToString(
					DateUtil.addDay(paper_expire_time, 10), "yyyy-MM-dd"));
			sceneParame.put("paper_money", mapBill.get("paper_money"));
			if (mapBill.get("userId") != null) {

				boolean send = noticeService.sendSysNotice(
						Long.parseLong(mapBill.get("userId").toString()),
						NoticeScene.TICKET_OVERDUE_REMIND, sceneParame);
				if (send) {
					success++;
				}
			} else {
				/* 查询短信验证码模板 */
				List<t_template_notice> noticeList = noticeService
						.queryTemplatesByScene(NoticeScene.TICKET_OVERDUE_REMIND);
				if (noticeList.size() <= 0) {
					continue;
				}
				String debt_mobile = mapBill.get("debt_mobile").toString();
				if (debt_mobile == null || "".equals(debt_mobile)) {
					continue;
				}
				success++;
				String content = noticeList.get(0).content;
				Map<String, String> param_format = StrUtil
						.mapToMap(sceneParame);
				content = StrUtil.replaceByMap(content, param_format);
				String smsAccount = settingService
						.findSettingValueByKey(SettingKey.SERVICE_SMS_ACCOUNT);
				String smsPassword = settingService
						.findSettingValueByKey(SettingKey.SERVICE_SMS_PASSWORD);
				/* 发送短信 */
				SMSUtil.sendSMS(smsAccount, smsPassword, debt_mobile, content);
				/* 添加一条短信发送控制记录 */
				sendCodeRecordsService.addSendCodeRecords(debt_mobile,
						FrontBaseController.getIp());
			}
			/* 关闭自动事务 */
			JPAPlugin.closeTx(false);
		}
		/* 开启自动投标事务 */
		JPAPlugin.startTx(false);
		result.code = 1;
		result.msg = "本次商票逾期提醒总共通知" + listOfWillExpireTicket.size() + "人次，成功通知"
				+ success + "人次!";

		return result;

	}

	/**
	 * 商票债权债务登记
	 * 
	 * @param type
	 * @param company_info
	 * @param company
	 * @param crd
	 * @param paper_money
	 * @param paper_pic_on
	 * @param paper_pic_under
	 * @param paper_expire_time
	 * @param paper_create_time
	 * @param bill_code
	 * @param drawee
	 * @param account_num
	 * @param account_bank
	 * @return
	 * @author xiaojun
	 * @version 2017-6-9
	 */
	/*
	 * public t_commercial_paper_info addTicket(int type,t_company_info
	 * company_info ,t_company_info company,t_creditor_right_debt crd,double
	 * paper_money,String paper_pic_on,String paper_pic_under,String
	 * paper_expire_time,String paper_create_time,String bill_code,String
	 * drawee,String account_num,t_cib_bank cib_bank){ t_commercial_paper_info
	 * t= findByID(crd.commer_paper_id); if(t == null){ t=new
	 * t_commercial_paper_info(); }
	 * 
	 * t.paper_pic_on=paper_pic_on; t.paper_pic_under=paper_pic_under;
	 * t.paper_money=paper_money; t.paper_expire_time=
	 * DateUtil.strToDate(paper_expire_time, "yyyy/MM/dd");
	 * t.bill_code=bill_code; t.account_num=account_num; t.account_bank =
	 * cib_bank.bank_name;
	 * 
	 * t.bank_no = cib_bank.bank_no;
	 * t.paper_create_time=DateUtil.strToDate(paper_create_time, "yyyy/MM/dd");
	 * t.drawee=drawee; t.receive_id=company_info.user_id;
	 * t.debt_creditor_id=crd.id; if(type==0){ t.receive_name=crd.creditor_name;
	 * t.receive_num=company.open_account; t.receive_bank=company.open_bank;
	 * }else if(type==1){ t.receive_name=company_info.full_name;
	 * t.receive_num=company_info.open_account;
	 * t.receive_bank=company_info.open_bank; }
	 * 
	 * return addTicket(t); }
	 */
	/**
	 * 根据商票id删除
	 * 
	 * @param id
	 * @return
	 * @author xiaojun
	 * @version 2017-6-9
	 */
	public boolean deleteTicket(long id) {
		int i = commerciaPaperiInfoDao.delete(id);
		return i == 1 ? true : false;
	}

	/**
	 * 查商票 -app
	 * 
	 * @param commer_paper_id
	 * @return
	 * @author zhiliang.lan
	 * @createDate 2017年8月1日
	 */
	public Map<String, Object> findcommercialPaperInfoByIDApp(long commerPaperId) {

		return commerciaPaperiInfoDao
				.findcommercialPaperInfoByIDApp(commerPaperId);
	}

	/**
	 * 查询单个商票信息---获取当前输入的票号是否存在
	 * 
	 * @param id
	 * @return t_commercial_paper_info
	 * @author liaijun
	 * @createDate 2017年8月1日
	 */
	public boolean findPaperNo(String no) {
		List<t_commercial_paper_info> list = findListByColumn("bill_code = ?",
				no);
		if (list == null || list.size() == 0) {
			return false;
		}
		return true;
	}

	/**
	 * 校验
	 * 
	 * @param creditorId
	 *            债务id
	 * @param paper_money
	 *            金额
	 * @param cpl
	 *            额度实体
	 * @param crd
	 *            债权实体
	 * @param digitalCommercialPaper
	 *            数字商票实体
	 * @param payment_time
	 *            到期时间
	 * @param isDigital
	 *            是否是数字商票
	 * @return
	 * @author xiaojun
	 * @version 2017-11-17
	 */
	public ResultInfo savePaperValidate(long creditorId, double paper_money,
			 t_creditor_right_debt crd,int is_digital, int ticket_away, double usable_limit, long userid,
			double custodian_fee, double flow_limit, int cpiType, int isDigital) {
		ResultInfo result = new ResultInfo();
		if (crd == null) {
			result.code = -1;
			result.msg = "债权信息异常";
			return result;
		} else if (crd.company_id <= 0) {
			result.code = -1;
			result.msg = "请先通知债权人在本平台注册！";
			return result;
		}
		if (ticket_away == 1 && is_digital == 1) {
			result.code = -1;
			result.msg = "转开功能关闭";
			return result;
		}
		if (creditorId <= 0) {
			result.code = -1;
			result.msg = "请选择债务信息";
			return result;
		}
		if (paper_money <= 0) {
			result.code = -1;
			result.msg = "转开金额异常";
			return result;
		}
		if (paper_money > usable_limit) {
			result.code = -1;
			result.msg = "可用授信额度不足，请申请授信额度！";
			return result;
		}
		
		if (paper_money > crd.rest_debt_money) {
			result.code = -1;
			result.msg = "转开金额不能大于债权剩余金额";
			return result;
		}
		if (paper_money > flow_limit && cpiType == 0) {
			result.code = -1;
			result.msg = "单笔融通面额不超过" + flow_limit + "元";
			return result;
		}
		

		// 如果不是数字商票，则不用进行流转费用的结算
		if (isDigital == 1) {
			t_user_fund user_fund = userFundService
					.queryUserFundByUserId(userid);
			if (user_fund == null) {
				result.code = -1;
				result.msg = "用户资金账户异常！！";
				return result;
			}
			result = userFundService.userFundSignCheck(userid);
			if (result.code < 0) {
				return result;
			}
			if (user_fund.balance < custodian_fee) {
				result.code = -1;
				result.msg = "余额不足缴纳票信额度管理费！需支付" + custodian_fee +"元";
				return result;
			}
		}

		result.code = 1;
		result.msg = "校验通过";
		return result;
	}

	/**
	 * 前台-账户中心-交易管理-商票列表-数字商票转开-新增商票信息和数字商票表信息
	 * 
	 * @param digitalCommercialPaper
	 *            数字商票实体
	 * @param paper_money
	 *            转开金额
	 * @param paper_expire_time
	 *            到期时间
	 * @param creditorId
	 *            选中债权表id
	 * @param cplid
	 *            额度表id
	 * @param cpiId
	 *            上一张商票表id
	 * @param isDigital
	 *            是否是数字商票 0 不是 1 是
	 * @return
	 * @author xiaojun
	 * @version 2017-5-13
	 * @param leader_custodian_fee 
	 */

	public ResultInfo savePaperInfo(double paper_money, long creditorId,
			t_user_credit user_credit, long cpiId, int ticket_away,
			long userid, String certificate_code, String contract_name_code,
			t_commercial_paper_info olcpi, double custodian_fee, int cpiType,
			t_user_credit oluserCredit, int isDigital, double leader_custodian_fee) {
		ResultInfo result = new ResultInfo();
		t_creditor_right_debt crd = creditorRightDebtService
				.findByID(creditorId);
		
		// 增加受让额度
		t_user_credit userCredit = userCreditService.findByUserTransfer(
				crd.company_id, user_credit.id, oluserCredit.credit_granting_code);
		if (userCredit == null) {
			userCredit = new t_user_credit();
			userCredit.time = new Date();
			userCredit.setStatus(AuditResult.TRANSFER);
			userCredit.user_id = crd.company_id;
			userCredit.user_name = crd.creditor_name;
			userCredit.credit_granting_code = userCreditService
					.getGrantingCcode(oluserCredit.credit_granting_code);
			userCredit.start_time = user_credit.start_time;
			userCredit.end_time = user_credit.end_time;
			userCredit.financing_confine_limit = user_credit.financing_confine_limit;
			userCredit.bond_percent = user_credit.bond_percent;
			userCredit.custodian_fee = user_credit.custodian_fee;
			userCredit.flow_limit = user_credit.flow_limit;
			userCredit.parent_id = user_credit.id;
			userCredit.lender_id = user_credit.lender_id;
			userCredit.lender_name = user_credit.lender_name;
		}
		userCredit.transferee_limit += paper_money;
		userCredit.transferee_used_limit += paper_money;
		userCredit.usable_limit += paper_money;
		boolean saveCredit = userCreditService.save(userCredit);
		if (!saveCredit) {
			LoggerUtil.error(false, "更新收票人授信额度异常");
			result.code = -1;
			result.msg = "更新收票人授信额度异常";
			return result;
		}

		t_digital_commercial_paper digitalCommercialPaper = new t_digital_commercial_paper();
		digitalCommercialPaper.pledge_code = oluserCredit.credit_granting_code;
		digitalCommercialPaper.pledge_drawer_time = oluserCredit.start_time;
		digitalCommercialPaper.pledge_expire_time = oluserCredit.end_time;
		digitalCommercialPaper.billing_time = new Date();
		digitalCommercialPaper.certificate_code = certificate_code;
		digitalCommercialPaper.lender_id = oluserCredit.lender_id;
		digitalCommercialPaper.lender_name = oluserCredit.lender_name;
		digitalCommercialPaper.payment_time = olcpi.paper_expire_time;
		digitalCommercialPaper.contract_name_code = contract_name_code;
		digitalCommercialPaper.digital_com_paper_money = paper_money;
		digitalCommercialPaper.credit_limit_id = oluserCredit.id;
		digitalCommercialPaper.company_credit_id = oluserCredit.id;
		digitalCommercialPaper.receive_credit_id = userCredit.id;

		t_commercial_paper_info cpi = new t_commercial_paper_info();
		cpi.paper_money = paper_money;
		cpi.paper_expire_time = digitalCommercialPaper.payment_time;
		cpi.bill_code = digitalCommercialPaper.certificate_code.substring(2);

		t_company_info companyInfo = companyInfoService
				.findCompanyInfoByUserId(userid);
		String drawee = companyInfo.full_name;
		cpi.account_num = companyInfo.open_account;
		cpi.account_bank = companyInfo.open_bank;
		cpi.paper_create_time = new Date();
		cpi.drawee = drawee;
		// 持票人id
		cpi.receive_id = userid;// currUser.id ？
		cpi.is_digital = 1;
		cpi.debt_creditor_id = creditorId;
		cpi.time = new Date();
		// 原始商票id
		if (olcpi.is_digital == 0 || olcpi.orginal_paper_id == 0) {
			cpi.orginal_paper_id = cpiId;
		} else {
			cpi.orginal_paper_id = olcpi.orginal_paper_id;
		}

		cpi.certificate_code = digitalCommercialPaper.certificate_code;

		cpi.receive_name = crd.creditor_name;
		t_company_info company = companyInfoService
				.findCompanyInfoByUserId(crd.company_id);
		cpi.receive_num = company.open_account;
		cpi.receive_bank = company.open_bank;
		digitalCommercialPaper.drawer = drawee;
		digitalCommercialPaper.is_allow_turn = ticket_away;
		digitalCommercialPaper.digital_com_paper_money = paper_money;
		if (cpi.receive_num == null || cpi.receive_bank == null) {
			result.code = -1;
			result.msg = "债权人开户银行资料不完善！";
			return result;
		}
		if (cpi.account_num == null || cpi.account_bank == null) {
			result.code = -1;
			result.msg = "债务人开户银行资料不完善！";
			return result;
		}
		cpi.paper_pic_on = ImgUtil.screenshot(digitalCommercialPaper, 1, cpi,
				null);
		cpi.paper_pic_under = ImgUtil.screenshot(digitalCommercialPaper, 2,
				cpi, null);
		if (cpi.paper_pic_on == null) {
			result.code = -1;
			result.msg = "新增商票图片失败";
			return result;
		}
		cpi.bank_no = olcpi.bank_no;
		cpi.lender_id = oluserCredit.lender_id;
		cpi.lender_name = oluserCredit.lender_name;
		
		//TODO
		//商票的原始授信
		if(user_credit.parent_id == 0){
			cpi.receive_credit_id = user_credit.id;
		}else{
			cpi.receive_credit_id = user_credit.parent_id;
		}
		
		cpi.finacing_residue_limit = paper_money;
		// 使用原始授信数据的融通比例
		cpi.finacing_ratio = user_credit.financing_confine_limit;
		cpi.paper_status = TicketStatus.TBC.code;
		cpi.credit_limit_id = userCredit.id;
		// 新增商票
		cpi = addTicket(cpi);
		if (cpi.id == null) {
			result.code = -1;
			result.msg = "新增商票信息失败";
			return result;
		}
		
		digitalCommercialPaper.finacing_ratio = cpi.finacing_ratio;
		digitalCommercialPaper.contract_name_code = crd.contract_name_code;
		digitalCommercialPaper.company_id = userid;// currUser.id
		digitalCommercialPaper.original_id = olcpi.id;
		digitalCommercialPaper.commer_paper_id = cpi.id;
		digitalCommercialPaper.receive_id = crd.company_id;
		digitalCommercialPaper.receive_person = crd.creditor_name;
		digitalCommercialPaper.pledge_current_time = new Date();
		digitalCommercialPaper.debt_creditor_id = creditorId;
		digitalCommercialPaper.credit_limit_id = oluserCredit.id;
		digitalCommercialPaper.digital_com_pic_on = cpi.paper_pic_on;
		digitalCommercialPaper.digital_com_pic_under = cpi.paper_pic_under;
		// 新增数字商票
		digitalCommercialPaper = digitalCommercialPaperService
				.saveDigitalPapre(digitalCommercialPaper);
		if (digitalCommercialPaper.id == null) {
			result.code = -1;
			result.msg = "新增数字商票信息失败";
			return result;
		}
		String code="";
		// 更新开票人额度信息
		if (digitalCommercialPaper.credit_limit_id != user_credit.id) {
			oluserCredit.usable_limit -= paper_money;
			oluserCredit.transfer_used_limit += paper_money;
			saveCredit = userCreditService.updateLimit(oluserCredit);
			if (!saveCredit) {
				LoggerUtil.error(false, "更新授信额度异常");
				result.code = -1;
				result.msg = "更新授信额度异常";
				return result;
			}
			code=oluserCredit.credit_granting_code;
		}else{
			user_credit.usable_limit -= paper_money;
			user_credit.transfer_used_limit += paper_money;
			saveCredit = userCreditService.updateLimit(user_credit);
			if (!saveCredit) {
				LoggerUtil.error(false, "更新授信额度异常");
				result.code = -1;
				result.msg = "更新授信额度异常";
				return result;
			}
			code=user_credit.credit_granting_code;
		}
		// 更新商票额度
		olcpi.finacing_residue_limit -= paper_money;
		if (olcpi.finacing_residue_limit < 0) {
			result.code = -1;
			result.msg = "更新授信额度异常";
			return result;
		}
		boolean saveCpi = updateTicket(olcpi);
		if (!saveCpi) {
			LoggerUtil.error(false, "更新商票额度异常");
			result.code = -1;
			result.msg = "更新商票额度异常";
			return result;
		}

		// 添加开票人额度明细表信息
		String service_order_no = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_AVERT, "");
		t_user_credit_detail amountDetail = new t_user_credit_detail(
				new Date(), userid, drawee, 0,
				code, user_credit.start_time,
				user_credit.end_time, user_credit.lender_id,
				user_credit.lender_name, 0, paper_money, 0, 0, 0,
				-paper_money, service_order_no,
				ServiceType.TICKET_AVERT.value, cpi.receive_credit_id, 0);
		boolean saveDetail = userCreditDetailService.save(amountDetail);
		if (!saveDetail) {
			LoggerUtil.error(false, "新增开票人额度明细异常");
			result.code = -1;
			result.msg = "新增额度明细异常";
			return result;
		}
		// 添加收票人额度明细表信息
		service_order_no = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_TRANSFEREE, "");
		amountDetail = new t_user_credit_detail(new Date(),
				digitalCommercialPaper.receive_id,
				digitalCommercialPaper.receive_person, 0,
				userCredit.credit_granting_code, user_credit.start_time,
				user_credit.end_time, user_credit.lender_id,
				user_credit.lender_name, 0, 0, paper_money, 0, 0,
				paper_money, service_order_no,
				ServiceType.TICKET_TRANSFEREE.value, cpi.receive_credit_id,
				userid);
		saveDetail = userCreditDetailService.save(amountDetail);
		if (!saveDetail) {
			LoggerUtil.error(false, "新增收票人额度明细异常");
			result.code = -1;
			result.msg = "新增额度明细异常";
			return result;
		}
		// 更新债权债务表的剩余额度数据
		crd = creditorRightDebtService.findByID(creditorId);
		crd.rest_debt_money -= paper_money;
		if (crd.rest_debt_money == 0) {
			//crd.status = t_creditor_right_debt.CreditorRightDebtStatus.LOSE_EFFICACY.code;
		}
		boolean save = creditorRightDebtService.addCreditorRightDebt(crd);
		if (!save) {
			LoggerUtil.error(false, "债权剩余金额更新异常");
			result.code = -1;
			result.msg = "债权剩余金额更新异常";
			return result;
		}

		
		//TODO
		// 收取票信额度管理费,先冻结，如果不是数字商票不需要进行冻结金额
		if ( oluserCredit.parent_id != 0 && custodian_fee > 0) {
			boolean saveFreeze = userFundService.userFundFreeze(userid,
					custodian_fee);
			if (!saveFreeze) {
				result.code = -1;
				result.msg = "冻结额度管理费失败！";
				return result;
			}
			t_user_fund userFund = userFundService
					.queryUserFundByUserId(userid);
			String serviceOrderNo = OrderNoUtil.getNormalOrderNo(
					ServiceType.TICKET_AVERT, "");
			/** 添加用户交易记录 */
			Map<String, String> summaryPrams = new HashMap<String, String>();
			summaryPrams.put("amount", custodian_fee + "");
			summaryPrams.put("certificate_code", digitalCommercialPaper.certificate_code);
			boolean addDeal = dealUserService.addDealUserInfo(
					serviceOrderNo, // 订单号
					userid, custodian_fee, userFund.balance, userFund.freeze,
					t_deal_user.OperationType.CUSTODIAN_FEE, summaryPrams);

			if (!addDeal) {
				result.code = -1;
				result.msg = "添加交易记录失败！";
				return result;
			}
		}
		// 收取票信流转服务费,先冻结，如果不是数字商票不需要进行冻结金额
		if ( oluserCredit.parent_id != 0 && leader_custodian_fee > 0) {
			boolean saveFreeze = userFundService.userFundFreeze(oluserCredit.lender_id,
					leader_custodian_fee);
			if (!saveFreeze) {
				result.code = -1;
				result.msg = "冻结票信流转服务费失败！";
				return result;
			}
			t_user_fund userFund = userFundService
					.queryUserFundByUserId(oluserCredit.lender_id);
			String serviceOrderNo = OrderNoUtil.getNormalOrderNo(
					ServiceType.TICKET_AVERT, "");
			/** 添加用户交易记录 */
			Map<String, String> summaryPrams = new HashMap<String, String>();
			summaryPrams.put("certificate_code", digitalCommercialPaper.certificate_code);
			summaryPrams.put("amount", leader_custodian_fee + "");
			boolean addDeal = dealUserService.addDealUserInfo(
					serviceOrderNo, // 订单号
					oluserCredit.lender_id, leader_custodian_fee, userFund.balance, userFund.freeze,
					t_deal_user.OperationType.FREEZE_FETCH_PAY_PLAT_CREDIT, summaryPrams);
			
			if (!addDeal) {
				result.code = -1;
				result.msg = "添加交易记录失败！";
				return result;
			}
		}

		// 发送通知
		t_company_info company_info = companyInfoService
				.findCompanyInfoByUserId(digitalCommercialPaper.receive_id);
		if (company_info == null) {
			result.code = -1;
			result.msg = "收票人信息不存在！";
			return result;
		}
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", company_info.full_name);
		param.put("drawee", drawee);
		noticeService.sendSysNotice(company_info.user_id,
				NoticeScene.OPEN_TIOCKET_AFFIRM, param);

		result.code = 1;
		result.msg = "新增数字商票信息成功";
		result.obj = digitalCommercialPaper;
		return result;
	}

	/**
	 * 修改商票状态
	 * 
	 * @param status
	 * @param olStatus
	 *            图片地址
	 * @param id
	 *            商票id
	 * @return
	 * @author xiaojun
	 * @createDate 2017年4月26日
	 */
	public int upPaperStatus(int status, int olStatus, long id) {

		return commerciaPaperiInfoDao.upPaperStatus(status, olStatus, id);

	}

	/**
	 * 根据账款凭证编号查询凭证信息
	 * 
	 * @param voucher_code
	 * @return
	 * @author xiaojun
	 * @version 2018-1-16
	 */
	public t_commercial_paper_info findByVoucherCode(String voucher_code) {

		return commerciaPaperiInfoDao.findByVoucherCode(voucher_code);
	}

	// /--------------------------------------------start-----------------------------------------
	/**
	 * 查询挂牌的信息（商票质押融通/数字账款凭证融通）
	 * 
	 * @param userId
	 * @param isDopist
	 *            true:数字账款凭证融通
	 * @param obj
	 * @author liaijun
	 * @version 2018年1月16日
	 */
	public List<PaperInfoToLoadBid> findPaperInfos(Long userId, Type type,
			Object... obj) {
		// 返回结果是否为数字商票
		return commerciaPaperiInfoDao.findPaperInfos(userId, type, obj);
	}

	/**
	 * 
	 * 设置商票的状态和返回额度
	 * 
	 * @param id
	 *            id
	 * @param amount
	 *            额度
	 * @return
	 * @author liaijun
	 * @version 2018年1月19日
	 */
	public int updatePaperinfoAmount(long id, double amount) {
		return commerciaPaperiInfoDao.updatePaperinfoAmount(id, amount);
	}

	/**
	 * 前台-交易管理-质押管理
	 * 
	 * @param showType
	 * @param currPage
	 * @param pageSize
	 * @param exports
	 * @param orderType
	 * @param orderValue
	 * @param creditorName
	 * @param numNo
	 * @param debtPersonName
	 * @return
	 * @author xiaojun
	 * @createDate 2017年4月15日
	 */
	public PageBean<CommercialPaperBean> pageOfPledgeTicketBond(int showType,
			int currPage, int pageSize, int exports, long user_id,
			String checkin_time, String to_checkin_time, int type,
			int is_digital,int is_old) {
		return commerciaPaperiInfoDao.pageOfPledgeTicketBond(showType, currPage,
				pageSize, exports, user_id, checkin_time, to_checkin_time,
				type, is_digital,is_old);

	}
	
	/**
	 * 校验
	 * 
	 * @param creditorId
	 *            债务id
	 * @param paper_money
	 *            金额
	 * @param cpl
	 *            额度实体
	 * @param crd
	 *            债权实体
	 * @param digitalCommercialPaper
	 *            数字商票实体
	 * @param payment_time
	 *            到期时间
	 * @param isDigital
	 *            是否是数字商票
	 * @return
	 * @author xiaojun
	 * @version 2017-11-17
	 * @param userCredit 
	 * @param leader_custodian_fee 
	 */
	public ResultInfo savePaperValidate(long creditorId, double paper_money,
			double finacing_residue_limit, t_creditor_right_debt crd,
			int is_digital, int ticket_away, double usable_limit, long userid,
			double custodian_fee, double flow_limit, int cpiType, t_user_credit userCredit, int isDigital, double leader_custodian_fee) {
		ResultInfo result = new ResultInfo();
		if (crd == null) {
			result.code = -1;
			result.msg = "债权信息异常";
			return result;
		} else if (crd.company_id <= 0) {
			result.code = -1;
			result.msg = "请先通知债权人在本平台注册！";
			return result;
		}
		if (ticket_away == 1 && is_digital == 1) {
			result.code = -1;
			result.msg = "转开功能关闭";
			return result;
		}
		if (creditorId <= 0) {
			result.code = -1;
			result.msg = "请选择债务信息";
			return result;
		}
		if (paper_money <= 0) {
			result.code = -1;
			result.msg = "转开金额异常";
			return result;
		}
		if (paper_money > usable_limit) {
			result.code = -1;
			result.msg = "可用授信额度不足，请申请授信额度！";
			return result;
		}
		if (paper_money > finacing_residue_limit) {
			result.code = -1;
			result.msg = "转开金额不能大于融通可用额度";
			return result;
		}
		if (paper_money > crd.rest_debt_money) {
			result.code = -1;
			result.msg = "转开金额不能大于债权剩余金额";
			return result;
		}
		if (paper_money > flow_limit && cpiType == 0) {
			result.code = -1;
			result.msg = "单笔融通面额不超过" + flow_limit + "元";
			return result;
		}
		if (crd.company_id == 0) {
			result.code = -1;
			result.msg = "债权人没有注册！";
			return result;
		}

		// 如果不是数字商票，则不用进行流转费用的结算
		if ( userCredit.parent_id != 0 && leader_custodian_fee > 0) {
			t_user_fund user_fund = userFundService
					.queryUserFundByUserId(userCredit.lender_id);
			if (user_fund == null) {
				result.code = -1;
				result.msg = "用户资金账户异常！！";
				return result;
			}
			result = userFundService.userFundSignCheck(userCredit.lender_id);
			if (result.code < 0) {
				return result;
			}
			if (user_fund.balance  < custodian_fee) {
				result.code = -1;
				result.msg = "放款人余额不足缴纳票信流转受让服务费！需支付" + leader_custodian_fee +"元";
				
				Map<String, Object> param = new HashMap<String, Object>();
				param.put("user_name", userCredit.lender_name);
				param.put("leader_custodian_fee", leader_custodian_fee);
				noticeService.sendSysNotice(userCredit.lender_id,
						NoticeScene.TICKET_TRANSFER_FEE, param);
				return result;
			}
			
			
		}
		// 如果不是数字商票，则不用进行票信管理费的结算
		if ( userCredit.parent_id != 0 && custodian_fee > 0) {
			t_user_fund user_fund = userFundService
					.queryUserFundByUserId(userid);
			if (user_fund == null) {
				result.code = -1;
				result.msg = "用户资金账户异常！！";
				return result;
			}
			result = userFundService.userFundSignCheck(userid);
			if (result.code < 0) {
				return result;
			}
			if (user_fund.balance < custodian_fee) {
				result.code = -1;
				result.msg = "您余额不足缴纳票信额度受让管理费！需支付" + custodian_fee +"元";
				return result;
			}
		}
		result.code = 1;
		result.msg = "校验通过";
		return result;
	}

	/**
	 * 在用户利用商票转开凭证后又撤票或者被拒收的时候，返还可用额度给原商票
	 * @param orgcpi 商票信息表
	 * @return
	 * @author Liangqiongfeng
	 *@version 2018-3-10 
	 */
	public boolean save(t_commercial_paper_info orgcpi) {
		
		return commerciaPaperiInfoDao.save(orgcpi);
	}

	/**
	 *	查询当前授信下的所有商票
	 * @param user_id 商票持有人id
	 * @param credit_limit_id 用户授信额度表的id
	 * @return
	 * @author LiangQiongfeng
	 *@version 2018-3-13 
	 */
	public List<t_commercial_paper_info> findByUserId(long user_id,Long credit_limit_id) {
		
		return commerciaPaperiInfoDao.findByUserId(user_id,credit_limit_id);
	}

	
	/**
	 * 更新额度
	 *
	 * @param type 类型
	 * @param amount 金额
	 * @param paperId 归还的商票id
	 * @param user_id 接收额度人的id
	 * @param creditLineID 授信额度id
	 * @return
	 * @author xiaojun
	 *@version 2018年1月30日
	 */
	public ResultInfo doStillQuota(Type type ,double amount,long user_id,long creditLineID){
		ResultInfo resultInfo = new ResultInfo();
		
		//额度明细表的流水号
		String serviceOrderNo = OrderNoUtil.getNormalOrderNo(ServiceType.FINCIAL,OrderNoUtil.SPECIAL_BILL);
		
		//查看授信额度表编号信息
		t_user_credit userCreditU = userCreditService.findByID(creditLineID);
		if(userCreditU == null){
			resultInfo.code = -1;
			resultInfo.msg = "获取授信额度信息失败";
			return resultInfo;
		}
		//添加额度明细表信息
		//TODO
		//添加额度明细表信息
		long creditUserId = userCreditU.parent_id;
		if(userCreditU.parent_id==0){
			creditUserId = userCreditU.id;
		}
	
		t_user user = userService.findByID(user_id);
		if(user == null){
			resultInfo.code = -1;
			resultInfo.msg = "获取持票人信息失败";
			return resultInfo;
		}
		t_user_credit_detail userCreditDetail = new t_user_credit_detail(new Date(),user_id,
				user.company_full_name,0,userCreditU.credit_granting_code,userCreditU.start_time,
				userCreditU.end_time,userCreditU.lender_id,userCreditU.lender_name,0,0,0,
				amount,0,amount,serviceOrderNo,"托收退还",creditUserId,0);
		
		if (!userCreditDetailService.save(userCreditDetail)) {
			resultInfo.code = -1;
			resultInfo.msg = "添加额度明细失败";
			return resultInfo;
		}
		//变更总的额度
		int flag = userCreditService.updateToUser(creditLineID, amount);
		if (flag < 1) {
			resultInfo.code = -1;
			resultInfo.msg = "更新额度信息失败";
			return resultInfo;
		}
		resultInfo.code = 1;
		resultInfo.msg = "额度归还成功";
		return resultInfo;
	}

	/**
	 *
	 * @param string
	 * @param condistion
	 * @return
	 * @author xiaojun
	 *@version 2018-4-10 
	 */
	public List<t_commercial_paper_info> findList() {
		//商票到期，给对应的保证金修改状态为待退回
		StringBuffer querySql = new StringBuffer("SELECT id, time, paper_pic_on, paper_pic_under, paper_money, paper_expire_time, bill_code, account_num, account_bank, paper_create_time, drawee, receive_id, is_digital, allow_transfer, debt_creditor_id, orginal_paper_id, certificate_code, paper_status, receive_name, receive_num, receive_bank, collection_status, cash_amount, cash_all_amount, cash_time, payment_or_dishonour, dishonour_excuse, repayment_status, pact_no, bank_no, lender_id, lender_name, credit_limit_id, finacing_ratio, finacing_residue_limit, finacing_used_limit, is_listing, circulation_id, is_endorse, receive_credit_id FROM t_commercial_paper_info WHERE paper_status = :paper_status");
		Map<String,Object> condistion = new HashMap<String, Object>();
		condistion.put("paper_status", TicketStatus.EXPIRE.code);
		
		return commerciaPaperiInfoDao.findListBySQL(querySql.toString(), condistion);
	}

	/**
	 * 撤销质押
	 * @param cpiId 商票id
	 * @param user_id 用户id
	 * @return
	 * @author liangqiongfeng
	 *@version 2018-4-20 
	 * @param type 
	 */
	public ResultInfo revocationPledge(long cpiId, long user_id, int type) {
		
		ResultInfo result = new ResultInfo();
		
		t_commercial_paper_info cpi = findByID(cpiId);
		
		if (null == cpi || cpi.paper_status != TicketStatus.REGISTER.code) {
			result.code = -1;
			result.msg = "商票状态异常！";
			return result;
		}
		
		
		if(type == 1){
			if (user_id != cpi.receive_id) {
				result.code = -1;
				result.msg = "警告！禁止操作";
				return result;
			}
			int i = upPaperStatus(TicketStatus.REVOCATION.code,
					TicketStatus.REGISTER.code, cpiId);
			if (i != 1) {
				result.code = -1;
				result.msg = "商票状态更新异常！";
				return result;
			}
		}
		if(type == 2){
			if (user_id != cpi.lender_id) {
				result.code = -1;
				result.msg = "警告！禁止操作";
				return result;
			}
			int i = upPaperStatus(TicketStatus.REJECTION.code,
					TicketStatus.REGISTER.code, cpiId);
			if (i != 1) {
				result.code = -1;
				result.msg = "商票状态更新异常！";
				return result;
			}
		}
		
		//增加融通申请质押商票的授信可质押额度
		t_user_credit userCredit = userCreditService.findByID(cpi.credit_limit_id);
		if(userCredit == null ){
			LoggerUtil.error(true,  "获取不到商票对应的授信信息！");
			result.code = -1;
			result.msg = "获取不到商票对应的授信信息！";
			return result;
		}
		
		userCredit.pledged_limit = userCredit.pledged_limit + cpi.paper_money;
		
		boolean flag = userCreditService.save(userCredit);
		if(!flag){
			LoggerUtil.error(true,  "更新商票对应的授信可质押额度异常！");
			result.code = -1;
			result.msg = "更新商票对应的授信可质押额度异常！";
			return result;
		}
		
		result.code = 1;
		if(type == 1){
			result.msg = "商票质押撤回操作成功";
		}else{
			result.msg = "商票质押拒收操作成功";
		}
		return result;
	}
}
